{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# `xeus-cling` 调用 C 代码"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 直接内联 C 代码"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "// 使用 extern \"C\" 包裹 C 代码\n",
    "extern \"C\" {\n",
    "    // C 语言函数定义\n",
    "    int add(int a, int b) {\n",
    "        return a + b;\n",
    "    }\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "7"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "// 在 C++ 中调用\n",
    "int result = add(3, 4);\n",
    "result  // 在 Notebook 中显示结果"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 调用预编译的 C 库"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "创建 C 头文件 `mylib.h`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Overwriting include/mylib.h\n"
     ]
    }
   ],
   "source": [
    "%%file include/mylib.h\n",
    "#ifndef MYLIB_H\n",
    "#define MYLIB_H\n",
    "\n",
    "int multiply(int a, int b);\n",
    "\n",
    "#endif"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "创建 C 源文件 `mylib.c`："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Overwriting src/mylib.c\n"
     ]
    }
   ],
   "source": [
    "%%file src/mylib.c\n",
    "#include \"mylib.h\"\n",
    "\n",
    "int multiply(int a, int b) {\n",
    "    return a * b;\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "编译为共享库："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "!gcc -shared -fPIC -o .temp/libmymath.so src/mylib.c -Iinclude"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "在 `xeus-cling` 中调用："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "// 加载动态库\n",
    "#pragma cling add_library_path(\".temp\")  // 指定库路径\n",
    "#pragma cling load(\"mymath\") // 加载 libmymath.so\n",
    "\n",
    "// 声明 C 函数\n",
    "extern \"C\" {\n",
    "    int multiply(int a, int b);\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "30"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "// 调用函数\n",
    "multiply(5, 6)  // 输出 30"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "C++14",
   "language": "C++14",
   "name": "xcpp14"
  },
  "language_info": {
   "codemirror_mode": "text/x-c++src",
   "file_extension": ".cpp",
   "mimetype": "text/x-c++src",
   "name": "c++",
   "version": "14"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
